#!/usr/bin/env python
#
# This file is released under the terms of the Artistic License.
# Please see the file LICENSE, included in this package, for details.
#
# Copyright (C) 2010 Mark Wong & Open Source Development Labs, Inc.
#               2006 Rilson Nascimento
#

# Because of the massive number of arguments we could have, use long-style only
# options.

from optparse import OptionParser
from os import system
from os.path import isfile, realpath
from subprocess import PIPE, Popen
from re import sub

parser = OptionParser(usage = 'usage: %prog --dbms <dbms> --i <dir> --o <dir> [options]')
parser.add_option('--dbms', help = 'dbms used <pgsql>')
parser.add_option('--dbname', help = 'dbname, for use with pgsql')
parser.add_option('--devices',
		help = 'comma delimited devices to plot (iostat)')
parser.add_option('--i', help = 'dbt5 results directory')
parser.add_option('--o', help = 'output directory')
options, args = parser.parse_args()

if not options.dbms:
    parser.error('--dbms flag required')
else:
    # Validate supported dbms.

    dbms = options.dbms
    if dbms == 'pgsql':
        if not options.dbname:
            parser.error('"--dbms pgsql" requires --dbname to be used')
        else:
            dbname = options.dbname
    else:
        parser.error('unrecognized dbms')
        exit(1)

if not options.i:
    parser.error('--i flag required')

if not options.o:
    parser.error('--o flag required')

indir = realpath(options.i)
outdir = realpath(options.o)
mixfile = '%s/driver/mix.log' % indir

device_arg = ''
if options.devices:
    device_arg = options.devices

# Needs to match the definitions in inc/CETxnMixGenerator.h.
sd = '0'
bv = '1'
cp = '2'
mw = '3'
ts = '4'
tl = '5'
to = '6'
tu = '7'
mf = '8'
tr = '9'
dm = '10'
tc = '11'

transaction_name = dict()
transaction_name[to] = 'Trade Order'
transaction_name[tr] = 'Trade Result'
transaction_name[tl] = 'Trade Lookup'
transaction_name[tu] = 'Trade Update'
transaction_name[ts] = 'Trade Status'
transaction_name[cp] = 'Customer Position'
transaction_name[bv] = 'Broker Volume'
transaction_name[sd] = 'Security Detail'
transaction_name[mf] = 'Market Feed'
transaction_name[mw] = 'Market Watch'
transaction_name[dm] = 'Data Maintenance'
transaction_name[tc] = 'Trade Cleanup'

print ( 'Generating transaction distribution charts...' )
for key in [sd, bv, cp, mw, ts, tl, to, tu, mf, tr, dm, tc]:
    system('dbt-plot-transaction-distribution "%s" %s %s %s/txn min 12 %d' % \
            (transaction_name[key], key, mixfile, outdir, int(key) + 1))

print ( 'Generating mpstat charts...' )
mpstatfile = '%s/driver/mpstat.out' % indir
if isfile(mpstatfile):
    system('dbt-plot-mpstat %s %s/driver/mpstat' % (mpstatfile, outdir))

mpstatfile = '%s/db/mpstat.out' % indir
if isfile(mpstatfile):
    system('dbt-plot-mpstat %s %s/db/mpstat' % (mpstatfile, outdir))

print ( 'Generating iostat charts...' )
iostatfile = '%s/driver/iostatx.out' % indir
if isfile(iostatfile):
    system('dbt-plot-iostat %s %s/driver/iostat %s' % \
            (iostatfile, outdir, device_arg))

iostatfile = '%s/db/iostatx.out' % indir
if isfile(iostatfile):
    system('dbt-plot-iostat %s %s/db/iostat %s' % \
            (iostatfile, outdir, device_arg))

print ( 'Generating vmstat charts...' )
vmstatfile = '%s/driver/vmstat.out' % indir
if isfile(vmstatfile):
    system('dbt-plot-vmstat %s %s/driver/vmstat' % (vmstatfile, outdir))

vmstatfile = '%s/db/vmstat.out' % indir
if isfile(vmstatfile):
    system('dbt-plot-vmstat %s %s/db/vmstat' % (vmstatfile, outdir))

print ( 'Generating transaction rate charts...' )
system('dbt5-plot-transaction-rate %s %s/txn' % (mixfile, outdir))

print ( 'Generating database statistics charts...' )
if dbms == 'pgsql':
    system('dbt-pgsql-plot-database-stats ' \
            '%s/db/pg_stat_databases.out %s %s/db' % (indir, dbname, outdir))

    # This relies on the scripts for PostgreSQL to generate these
    # table-list.txt and index-list.txt files.
    f = None
    try:
        f = open('%s/db/table-list.txt' % indir)
    except:
        print ( 'Cannot open table list to generate database table stats, ' \
                'continuing...' )

    if f is not None:
        for table in f:
            system('dbt-pgsql-plot-table-stats %s/db/pg_stat_tables.out ' \
                    '%s %s/db/tables' % (indir, table.strip(), outdir))
        f.close()

    f = None
    try:
        f = open('%s/db/index-list.txt' % indir)
    except:
        print ( 'Cannot open index list to generate database index stats, ' \
                'continuing...' )

    if f is not None:
        for index in f:
            system('dbt-pgsql-plot-index-stats %s/db/pg_stat_indexes.out ' \
                    '%s %s/db/indexes' % (indir, index.strip(), outdir))
        f.close()

reportfile = '%s/index.html' % outdir
try:
    h = open(reportfile, 'w')
except:
    print ( 'Cannot open file: %s' % reportfile )
    exit(3)

h.write('<html>\n')
h.write('<head>\n')
h.write('<title>Database Test 5 Report</title>\n')
h.write('</head>\n')
h.write('<body>\n')
h.write('<h1>Database Test 5 Report</h1>\n')

h.write('<p>\n')

cmd = 'head -n 1 %s/readme.txt' % indir
p = Popen(cmd.split(), stdout=PIPE)
h.write(p.communicate()[0])

h.write('</p>\n')

h.write('<table>\n')

h.write('<tr>\n')
h.write('<td>\n')
h.write('<table>\n')
h.write('<caption>Results Summary</caption>\n')

h.write('<tr>\n')
h.write('<td align="right">Trade Result Transactions per Second:</td>\n')

cmd = 'grep trtps %s/results.txt' % indir
p = Popen(cmd.split(), stdout=PIPE)
h.write('<td>%s</td>\n' % p.communicate()[0].split()[0])

h.write('</tr>\n')

h.write('<tr>\n')
h.write('<td align="right">Customers:</td>\n')

cmd = 'grep Customer %s/readme.txt' % indir
p = Popen(cmd.split(), stdout=PIPE)
h.write('<td>%s</td>\n' % p.communicate()[0].split()[3])

h.write('</tr>\n')

h.write('<tr>\n')
h.write('<td align="right">Test Duration (minutes):</td>\n')

cmd = 'grep Duration %s/readme.txt' % indir
p = Popen(cmd.split(), stdout=PIPE)
h.write('<td>%0.1f</td>\n' % (float(p.communicate()[0].split()[2]) / 60.0))

h.write('</tr>\n')

h.write('</table>\n')
h.write('</td>\n')
h.write('<td>\n')
chart = 'txn/t%s-transaction-rate.png' % tr
h.write('<a href="%s"><img width="128" src="%s" height="96" />\n' % \
        (chart, chart))
h.write('</td>\n')
h.write('</tr>\n')

h.write('</table>\n')

h.write('<table border=1>\n')
h.write('<caption>Transaction Summary</caption>\n')

h.write('<tr>\n')
h.write('<th colspan=2>Transaction</th>\n')
h.write('<th colspan=2>Response Time (seconds)</th>\n')
h.write('<th colspan=5></th>\n')
h.write('<th colspan=2>Charts</th>\n')
h.write('</tr>\n')

h.write('<tr>\n')
h.write('<th>Name</th>\n')
h.write('<th>Mix %</th>\n')
h.write('<th>Average</th>\n')
h.write('<th>90th %</th>\n')
h.write('<th>Total</th>\n')
h.write('<th>Rollbacks</th>\n')
h.write('<th>%</th>\n')
h.write('<th>Warnings</th>\n')
h.write('<th>Invalid</th>\n')
h.write('<th>Transaction Rate</th>\n')
h.write('<th>Response Time Distribution</th>\n')
h.write('</tr>\n')

count = 0
for transaction in ['Security', 'Broker', 'Position', 'Watch', 'Status',
        'Lookup', 'Order', 'Update', 'Feed', 'Result',  'Data']:
    cmd = 'grep %s %s/results.txt' % (transaction, indir)
    p = Popen(cmd.split(), stdout=PIPE)
    c = sub(':', ' ', p.communicate()[0])
    c = sub('%', ' ', c)
    c = c.split()

    h.write('<tr>\n')
    h.write('<td>%s %s</td>\n' % (c[0], c[1]))
    h.write('<td>%s</td>\n' % c[2])
    h.write('<td>%s</td>\n' % c[3])
    h.write('<td>%s</td>\n' % c[4])
    h.write('<td>%s</td>\n' % c[5])
    h.write('<td>%s</td>\n' % c[6])
    h.write('<td>%s</td>\n' % c[7])
    h.write('<td>%s</td>\n' % c[8])
    h.write('<td>%s</td>\n' % c[9])
    chart = 'txn/t%d-transaction-rate.png' % count
    h.write('<td align="center">\n')
    h.write('<a href="%s"><img width="128" src="%s" height="96" />\n' % \
            (chart, chart))
    h.write('</td>\n')
    chart = 'txn/t%d-distribution.png' % count
    h.write('<td align="center">\n')
    h.write('<a href="%s"><img width="128" src="%s" height="96" />\n' % \
            (chart, chart))
    h.write('</td>\n')
    h.write('</tr>\n')
    count += 1

h.write('</table>\n')

h.write('<table>\n')
h.write('<caption>System Summary</caption>\n')

h.write('<tr>\n')
h.write('<td align="right">Operating System:</td>\n')

file = '%s/db/readme.txt' % indir
cmd = 'head -n 2 %s' % file
p = Popen(cmd.split(), stdout=PIPE)
c = p.communicate()[0].split('\n')
c1 = c[0].split()
c2 = c[1]
settings = 'db/proc.txt'
system('cp -p %s/db/proc.out %s/%s' % (indir, outdir, settings))
h.write('<td>%s %s %s</td>\n' % (c1[0], c1[2], c1[11]))
h.write('<td><a href="%s">Settings</a></td>\n' % settings)

h.write('</tr>\n')

h.write('<tr>\n')
h.write('<td align="right">Database Management System:</td>\n')
h.write('<td>%s</td>\n' % c2)

file1 = 'db/param.out'
if isfile('%s/%s' % (indir, file1)):
    file2 = 'db/param.txt'
    system('cp -p %s/%s %s/%s' % (indir, file1, outdir, file2))
    h.write('<td><a href="%s">Settings</a></td>\n' % file2)

file1 = 'db/plan0.out'
if isfile('%s/%s' % (indir, file1)):
    file2 = 'db/plan0.txt'
    system('cp -p %s/%s %s/%s' % (indir, file1, outdir, file2))
    h.write('<td><a href="%s">Query Plans</a></td>\n' % file2)

h.write('</tr>\n')

h.write('<tr>\n')

file = '%s/readme.txt' % indir
cmd = 'head -n 2 %s' % file
p = Popen(cmd.split(), stdout=PIPE)
c = p.communicate()[0].split('\n')

h.write('<td align="right">Notes:</td>\n')
h.write('<td>%s</td>\n' % c[1])

h.write('</tr>\n')

h.write('<tr>\n')
h.write('<td align="right">Driver Charts:</td>\n')
h.write('<td><a href="driver">View Directories</a></td>\n')
h.write('</tr>\n')

h.write('<tr>\n')
h.write('<td align="right">Database Charts:</td>\n')
h.write('<td><a href="db">View Directories</a></td>\n')
h.write('</tr>\n')

h.write('</table>\n')

h.write('</body>\n')
h.write('</html>\n')
